/*
* © 2010 Autodata Solutions Company. All Rights Reserved
* This source code is the confidential and proprietary information of Autodata Solutions Company.
* The user shall not, in whole or in part, copy, publish, disclose or make any use of this source code
* without the prior written consent of Autodata Solutions Company.
*
* File: net/autodata/compare/widgets/ResultsGrid.js
* Purpose: Provides custom implimintation of the compare results grid.
*
* Namespace: net.autodata.compare
* Requires:ExtJS,
*          ASC library - net/autodata/ascjs-ext-debug.js
*/

Ext.ns('net.autodata.compare.ResultsGrid');
(function() {
	
	//Because of the unexpected borders applied to the group header
	//ColumnModel's default calculation for the total width of the columns is off
	var ColumnModel = Ext.extend(Ext.grid.ColumnModel, {
		
		/**
	     * Returns the total width of all columns.
	     * @param {Boolean} includeHidden True to include hidden column widths
	     * @return {Number}
	     */
	    getTotalWidth : function(includeHidden) {
	        if (!this.totalWidth) {
	            this.totalWidth = 0;
	            for (var i = 0, len = this.config.length; i < len; i++) {
	                if (includeHidden || !this.isHidden(i)) {
	                    this.totalWidth += this.getColumnWidth(i);
	                }
	            }
	            
	            var colCount = this.getColumnCount(true);
	            
	            this.totalWidth += !Ext.isWebKit ? 2 : colCount * -1;
	            
	        }
	        return this.totalWidth;
	    }
	});
	
    var View = Ext.extend(Ext.grid.GroupingView, {
    	groupBorderWidth: 2,
    	
    	/**
	     * @private
	     * Returns the width of a given column minus its border width
	     * @return {Number} The column index
	     * @return {String|Number} The width in pixels
	     */
	    getColumnWidth : function(column) {
	        var columnWidth = this.cm.getColumnWidth(column),
	            borderWidth = this.borderWidth;
	        
	        if (Ext.isNumber(columnWidth)) {
	            if (Ext.isBorderBox || (Ext.isWebKit && !Ext.isSafari2)) {
	                return (columnWidth + borderWidth) + "px";
	            } else {
	                return Math.max(columnWidth - borderWidth, 0) + "px";
	            }
	        } else {
	            return columnWidth;
	        }
	    },
    	
        // private
        updateGroupWidths : function()
        {
            if(!this.canGroup() || !this.hasRows()){
                return;
            }
            var gbw = this.groupBorderWidth || 0;
            var tw = Math.max(this.cm.getTotalWidth(), this.el.dom.offsetWidth-this.getScrollOffset());
            tw = (tw - (this.grid.autoHeight ? gbw : 0)) +'px';
            var gs = this.getGroups();
            for(var i = 0, len = gs.length; i < len; i++){
                gs[i].firstChild.style.width = tw;
            }
        }
    });
    
    var STUBSTR = '<span class="{1}" recordId="{2}">{0}</span>';

    var Tip = Ext.extend(Ext.ToolTip, {

        closable: true,
        autoHide: false,

        closeAction: 'close',
        cls: 'a-grid-tip',
        anchor: 'right',

        close: function() {
            this.hide();
            this.destroy();
        },

        onRender: function() {
            Tip.superclass.onRender.apply(this, arguments);

            this.mon(this, 'show', function(e) {

                this.mon(Ext.getBody(), 'click', function(e, t) {
                    if (!e.within(this.el, false, true)) {
                        this.close();
                    }
                }, this);

            }, this, { delay: 30 });
        }
    });

    var Stub = Ext.extend(Object, {
        grid: undefined,

        /*Column Model Specific Attributes*/
        id: 'stub',
        header: 'stub',
        width: 181,
        sortable: false,
        dataIndex: 'description',

        constructor: function(cfg) {
            cfg = cfg || {};
            Ext.apply(this, cfg);
            this.initialConfig = cfg;
        },

        init: function(grid) {
            this.grid = grid;

            grid.on('destroy', this.onDestroy, this);
            grid.on('afterrender', this.onAfterRender, this);
        },

        renderer: function(value, metaData, record) {
            var feature = record.get('feature');
            return String.format(STUBSTR, value, feature ? 'a-qtip' : '', record.id);
        },

        onAfterRender: function() {
            this.grid.body.on('click', this.onFeatureClick, this, { delegate: '.a-qtip' });
        },

        onFeatureClick: function(e) {

            var grid = this.grid;
            var target = e.getTarget('span', undefined, true);
            var record = grid.getStore().getById(target.getAttribute('recordId'));

            if (!record) {
                return;
            }
            var feature = record.get('feature');
            var tip = new Tip({
                title: feature.title,
                items: [{ html: feature.description}],
                target: target
            });

            tip.mon(grid, 'bodyscroll', function() {
                //if scrolled, hide tip
                if (tip) {
                    tip.hide();
                }
            }, this, { buffer: 5 });

            tip.show();
        },

        onDestroy: function() {
            var g = this.grid;
            g.un('destroy', this.onDestroy, this);
            g.un('afterrender', this.onAfterRender, this);
            g.body.un('click', this.onFeatureClick, this);
        }
    });


    /*
    * Grid's column renderer for data output
    */
    function dataRenderer(value, metaData, record) {
        metaData.css = value.advantage ? 'highlight' : '';
        return value.data;
    }

    /**
    * ASC compare result grid panel.
    * @class ResultsGrid
    * @extends Ext.grid.GridPanel
    * @namespace net.autodata.compare.grid
    */
    var ResultsGrid = Ext.extend(Ext.grid.GridPanel, {
        ctCls: 'ct-compare-results-grid',
        autoHeight: true,
        width: 788,

        stubWidth: 181,
        baseWidth: 147,
        competitorWidth: 147,
        //lastCompetitorWidth: Ext.isWebKit ? Ext.isWindows ? 140 : 141 : Ext.isWindows ? Ext.isIE7 ? 134 : 135 : 136,
        lastCompetitorWidth: 151,

        columnLines: true,

        /**
        * ResultGrid object constructor
        * @method constructor
        */
        constructor: function(cfg) {
            cfg = cfg || {};
            var storeCfg = cfg.storeCfg || {};
            var stubCfg = cfg.stubCfg || {};

            delete cfg.storeCfg;

            var proxy = new net.autodata.data.HttpProxy({
                url: String.format('{0}/Ajax/Grids/Compare/', ASC.cfg.getLocaleContextPath())
            });

            storeCfg = Ext.apply(storeCfg, {
                reader: new Ext.data.JsonReader({ root: 'compare',
                    fields: [
                    { name: 'groupID', mapping: 'groupID' },
                    { name: 'groupName', mapping: 'groupName' },
                    { name: 'description', mapping: 'stub' },
                    { name: 'baseVehicle', mapping: 'baseVehicle' },
                    { name: 'competitor1', mapping: 'competitor1' },
                    { name: 'competitor2', mapping: 'competitor2' },
                    { name: 'competitor3', mapping: 'competitor3' },
                    { name: 'feature', convert: function(value, record) { return record.hasFeature ? { title: record.featureShortDesc, description: record.featureDesc} : null; } }
                    ]
                }),
                proxy: proxy,
                groupField: 'groupName',
                autoLoad: false,
                remoteStore: true,
                listeners: {
                    'loadexception': this.onLoadException,
                    scope: this
                }
            });

            cfg.store = new Ext.data.GroupingStore(storeCfg);

            var plugins = [].concat(cfg.plugins);
            delete cfg.plugins;
            
            var viewCfg = cfg.viewCfg;
            delete cfg.viewCfg;
            
            var view = new View(Ext.apply({
                borderWidth: 1,
                forceFit: false,
                enableNoGroups: false,
                enableGroupingMenu: false,
                showGroupName: false
            }, viewCfg));

            var stubColumn = new Stub({ width: this.stubWidth, fixed: true });
            plugins.push(stubColumn);
            
            var columns = [
                { id: 'groupName', header: 'groupName', width: 0, sortable: false, dataIndex: 'groupName', hidden: true },
                { id: 'groupID', header: 'groupID', width: 0, sortable: false, dataIndex: 'groupID', hidden: true },
                /*{ id: 'feature', header: 'feature', width: 0, sortable: false, dataIndex: 'feature', hidden: true },*/
                stubColumn,
                { id: 'baseVehicle', header: 'baseVehicle', width: this.baseWidth, sortable: false, dataIndex: 'baseVehicle', renderer: dataRenderer },
                { id: 'competitor1', header: 'competitor1', width: this.competitorWidth, sortable: false, dataIndex: 'competitor1', renderer: dataRenderer },
                { id: 'competitor2', header: 'competitor2', width: this.competitorWidth, sortable: false, dataIndex: 'competitor2', renderer: dataRenderer },
                { id: 'competitor3', header: 'competitor3', width: 0, sortable: false, dataIndex: 'competitor3', renderer: dataRenderer }
            ]
            
            //The last column's width needs to be adjusted based on the total number of columns
            function getOffset(scrollbarOffset)
            {	
            	var offset = (scrollbarOffset != undefined ? scrollbarOffset : Ext.getScrollBarWidth(true));
            	var adjust = offset - (!Ext.isWebKit ? 2 : 2);
            	return adjust > 0 ? adjust : 0;
            }
            var lcw = this.lastCompetitorWidth - getOffset(view.scrollOffset);
            columns[columns.length - 1].width = lcw;
            
            var cm = new ColumnModel({
                columns: columns
            });
            

            Ext.apply(cfg, {
                cls: 'compare-results-grid',
                enableDragDrop: false,
                enableColumnResize: false,
                enableColumnMove: false,
                enableColumnHide: false,
                enableHdMenu: false,
                border: false,
                hideHeaders: true,
                disableSelection: true,
                trackMouseOver: false,

                padding: '0 5px 5px 5px',

                cm: cm,
                view: view,

                plugins: plugins
            });

            ResultsGrid.superclass.constructor.call(this, cfg);
        },

        /**
        * Stores on load exeption event handler.
        * @method onLoadException
        * @private
        */
        onLoadException: function() {
            var store = this.getStore();
            store.removeAll();
        }
    });


    net.autodata.compare.ResultsGrid = ResultsGrid;
})();
